# -*- coding: utf-8 -*-
#-------------------------------------------------------------------------------
# Name:        master_main.py
# Purpose:     GAEDrive: common defination of master
#
# Author:      Crane Chu <cranechu (at) gmail.org>
#
# Created:     Nov. 20, 2009
# Copyright:   Copyright 2009,2010 Crane Chu
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#-------------------------------------------------------------------------------
#!/usr/bin/env python

__author__ = 'Crane Chu'


from google.appengine.ext import db
from django.utils import simplejson


# DEFINES
MAX_FETCH_COUNT = 1000 # GAE's limitation
CHUNK_SIZE = 128 * 1024
HTTP_OK = 200
PRE_ALLOC_CHUNKS = 8
ROOT_DIR = '/'
URLHEAD = 'http://' # replace to https if possible in CHINA GFW

# internal defination
_ATTRFIELDS = ['st_mode', 'st_ino', 'st_dev', 'st_nlink', 'st_uid',
               'st_gid', 'st_size', 'st_atime', 'st_mtime', 'st_ctime']

# data definition
class ChunkServer(db.Model):
    url = db.StringProperty()

    # space in bytes
    free = db.IntegerProperty()
    used = db.IntegerProperty()


class File(db.Model):
    name = db.StringProperty()
    parentdir = db.SelfReferenceProperty(collection_name = 'subfiles')
    # count of writing
    writing = db.IntegerProperty()
    # store file stat and xattr in JSON
    stat = db.StringProperty()
    xattr = db.StringProperty()
    # owner of the file
    owner = db.UserProperty()
    # sym link
    symlink = db.StringProperty()

    def __getattr__(self, name):
        if name in _ATTRFIELDS:
            return (simplejson.loads(self.stat))[name]
        else:
            return super(File, self).__getattr__(name)

    def __setattr__(self, name, value):
        if name in _ATTRFIELDS:
            stat = simplejson.loads(self.stat)
            stat[name] = value
            self.stat = simplejson.dumps(stat)
            return value
        else:
            return super(File, self).__setattr__(name, value)

    def getxattr(self, name):
        xattr = simplejson.loads(self.xattr)
        try:
            ret = xattr[name]
        except KeyError:
            ret = ''
        return ret
    
    def setxattr(self, name, value):
        xattr = simplejson.loads(self.xattr)
        xattr[name] = value
        self.xattr = simplejson.dumps(xattr)
        return value
    
    
class Chunk(db.Model):
    file = db.ReferenceProperty(File, collection_name = 'chunks')
    offset = db.IntegerProperty()   # in bytes
    length = db.IntegerProperty()   # in bytes
    server = db.ReferenceProperty(ChunkServer)
    chunk_key = db.StringProperty() # key of the chunk in chunk server


class OpenedFile(db.Model):
    file = db.ReferenceProperty(File, collection_name = 'opens')
    rand = db.IntegerProperty()
    readonly = db.BooleanProperty()
    time = db.DateTimeProperty(auto_now_add = True)
    
